+++ /dev/null
-#
-# Copyright (C) 2008-2017 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=radicale
-PKG_VERSION:=1.1.7
-PKG_RELEASE:=1
-
-PYPI_NAME:=Radicale
-PKG_HASH:=5b311b11f15db21a6000391eb3000ffc88ea8d7abbc91767dc54b771885be777
-
-PKG_MAINTAINER:=
-PKG_LICENSE:=GPL-3.0
-PKG_LICENSE_FILES:=COPYING
-PKG_CPE_ID:=cpe:/a:radicale:radicale
-
-include ../../lang/python/pypi.mk
-include $(INCLUDE_DIR)/package.mk
-include ../../lang/python/python3-package.mk
-
-define Package/radicale
- SECTION:=net
- CATEGORY:=Network
- SUBMENU:=Web Servers/Proxies
- TITLE:=Radicale CalDAV/CardDAV server
- URL:=https://radicale.org/
- DEPENDS:= \
- +python3-light \
- +python3-codecs \
- +python3-logging \
- +python3-openssl \
- +python3-urllib \
- +python3-xml
- USERID:=radicale=5232:radicale=5232
- PROVIDES:=radicale-py2 radicale-py3
-endef
-
-define Package/radicale/description
- The Radicale Project is a CalDAV (calendar) and CardDAV (contact) server. It
- aims to be a light solution, easy to use, easy to install, easy to configure.
- As a consequence, it requires few software dependances and is pre-configured to
- work out-of-the-box.
-endef
-
-define Package/radicale/conffiles
-/etc/config/radicale
-/etc/radicale/users
-/etc/radicale/rights
-endef
-
-define Py3Package/radicale/install
- $(INSTALL_DIR) $(1)/etc/init.d
- $(INSTALL_BIN) ./files/radicale.init $(1)/etc/init.d/radicale
-
- $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
- $(INSTALL_BIN) ./files/radicale.hotplug $(1)/etc/hotplug.d/iface/80-radicale
-
- $(INSTALL_DIR) $(1)/etc/config
- $(INSTALL_CONF) ./files/radicale.config $(1)/etc/config/radicale
-
- $(INSTALL_DIR) $(1)/etc/radicale/ssl
- $(INSTALL_DATA) ./files/config.template $(1)/etc/radicale/config.template
- $(INSTALL_DATA) ./files/logging.template $(1)/etc/radicale/logging.template
- $(INSTALL_DATA) ./files/radicale.users $(1)/etc/radicale/users
- $(INSTALL_DATA) ./files/radicale.rights $(1)/etc/radicale/rights
-
- $(INSTALL_DIR) $(1)/usr/bin
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/radicale $(1)/usr/bin/
-endef
-
-$(eval $(call Py3Package,radicale))
-$(eval $(call BuildPackage,radicale))
-$(eval $(call BuildPackage,radicale-src))
+++ /dev/null
-# -*- mode: conf -*-
-# vim:ft=cfg
-
-### AUTO-GENERATED CONFIGURATION
-### USED BY RADICALE
-### DO NOT EDIT
-### SEE /etc/config/radicale INSTEAD
-
-[server]
-# daemon # handled by /etc/init.d/radicale
-# pid # handled by /etc/init.d/radicale
-
-[encoding]
-
-[well-known]
-
-[auth]
-# htpasswd_filename # hard-coded /etc/radicale/users
-
-[git]
-
-[rights]
-# file # hard-coded /etc/radicale/rights
-
-[storage]
-
-[logging]
-# config # hard-coded /var/etc/radicale/logging
-
-[headers]
+++ /dev/null
-# -*- mode: conf -*-
-# vim:ft=cfg
-
-### AUTO-GENERATED CONFIGURATION
-### USED BY RADICALE
-### DO NOT EDIT
-### SEE /etc/config/radicale INSTEAD
-
-[loggers]
-keys = root
-
-[handlers]
-keys = console,file,syslog
-
-[formatters]
-keys = simple,full,syslog
-
-[logger_root]
-level = DEBUG
-handlers = console,file,syslog
-
-[handler_console]
-class = StreamHandler
-args = (sys.stdout,)
-formatter = simple
-# level = WARNING # set via /etc/config/radicale
-
-[handler_file]
-class = handlers.RotatingFileHandler
-formatter = full
-# level = INFO # set via /etc/config/radicale
-# args = ('[filename]','a',[maxbytes],[backupcount]) # set via /etc/config/radicale
-
-[handler_syslog]
-class = handlers.SysLogHandler
-args = ('/dev/log', handlers.SysLogHandler.LOG_DAEMON)
-formatter = syslog
-# level = WARNING # set via /etc/config/radicale
-
-[formatter_simple]
-format = %(message)s
-
-[formatter_full]
-format = %(asctime)s - %(levelname)s: %(message)s
-
-[formatter_syslog]
-format = radicale [%(process)d]: %(message)s
+++ /dev/null
-#
-# You find additional information on Radicale Homepage
-# http://radicale.org
-#
-# OpenWrt's wiki needs to be setup/updated ;-)
-#
-# if setting additional options please remember that UCI does not support
-# section names and option names with "-" (Dash) inside their name
-# to use them anyway replace "-" with "_" (Underscore)
-# Each Radicale's config [section] is setup as UCI config setting 'section'
-#
-
-####################################################
-# OpenWrt specific settings
-# not part of radicale package
-#
-config system 'radicale'
- # delayed startup at boot (default 10 seconds)
- # to wait for netifd to bring up interfaces
- # during this time iface hotplug events are ignored
-# option boot_delay '10'
-
-####################################################
-# Server options
-#
-config setting 'server'
-
- # hostname:port
- # IPv4 syntax: address:port
- # IPv6 syntax: [address]:port
- # ATTENTION:
- # only use ports > 1024 (non-privileged Ports)
- # because this implementation is running as non-root user
- # Default: 0.0.0.0:5232
-# list hosts '0.0.0.0:5232'
-# list hosts 'localhost:5232'
-
- # SSL flag, enable HTTPS protocol
- # Default: 0 (disabled)
-# option ssl '1'
-
- # SSL Protocol used. See python's ssl module for available values
- # Default: PROTOCOL_SSLv23
-# option protocol 'PROTOCOL_SSLv23'
-
- # Ciphers available. See python's ssl module for available ciphers
-# option ciphers ''
-
- # SSL certificate path and file
-# option certificate '/etc/radicale/ssl/server.crt'
-
- # SSL private key path and file
-# option key '/etc/radicale/ssl/server.key'
-
- # Reverse DNS to resolve client address in logs
- # Default: 0 (disabled)
-# option dns_lookup '1'
-
- # Message displayed in the client when a password is needed
-# option realm 'Radicale - Password Required'
-
-
-####################################################
-# Encoding options
-#
-config setting 'encoding'
-
- # Encoding for responding requests
-# option request 'utf-8'
-
- # Encoding for storing local collections
-# option stock 'utf-8'
-
-
-####################################################
-# Authentication options
-#
-config setting 'auth'
-
- # Authentication method
- # Value: None | htpasswd | IMAP | LDAP | PAM | courier | http | remote_user | custom
- # Default: None
- # if setting 'htpasswd' the file /etc/radicale/users is used (hardcoded)
-
- # Htpasswd encryption method
- # Value: plain | sha1 | ssha | crypt
-# option htpasswd_encryption 'crypt'
-
- # for other authenication methods consult Radicale documentation
- # and set options here
-
-
-####################################################
-# Git default options
-#
-config setting 'git'
-
- # Git default options
-
-
-####################################################
-# Rights backend
-#
-config setting 'rights'
-
- # Value: None | authenticated | owner_only | owner_write | from_file | custom
- # Default: None
- # if setting 'from_file' the file /etc/radicale/rights is used (hardcoded)
-
- # Custom rights handler
-# option custom_handler ''
-
-
-####################################################
-# Storage backend
-# -------
-# WARNING: ONLY "filesystem" IS DOCUMENTED AND TESTED,
-# OTHER BACKENDS ARE NOT READY FOR PRODUCTION.
-# -------
-#
-config setting 'storage'
- # Value: filesystem | multifilesystem | database | custom
- option type 'filesystem'
- option filesystem_folder '/srv/radicale'
-
-
-####################################################
-# Additional HTTP headers
-#
-config setting 'headers'
- # enable all if using CardDavMATE-, CalDavZAP- or InfCloud- WEBclient
-# list Access_Control_Allow_Origin '*'
-# list Access_Control_Allow_Methods 'GET'
-# list Access_Control_Allow_Methods 'POST'
-# list Access_Control_Allow_Methods 'OPTIONS'
-# list Access_Control_Allow_Methods 'PROPFIND'
-# list Access_Control_Allow_Methods 'PROPPATCH'
-# list Access_Control_Allow_Methods 'REPORT'
-# list Access_Control_Allow_Methods 'PUT'
-# list Access_Control_Allow_Methods 'MOVE'
-# list Access_Control_Allow_Methods 'DELETE'
-# list Access_Control_Allow_Methods 'LOCK'
-# list Access_Control_Allow_Methods 'UNLOCK'
-# list Access_Control_Allow_Headers 'User-Agent'
-# list Access_Control_Allow_Headers 'Authorization'
-# list Access_Control_Allow_Headers 'Content-type'
-# list Access_Control_Allow_Headers 'Depth'
-# list Access_Control_Allow_Headers 'If-match'
-# list Access_Control_Allow_Headers 'If-None-Match'
-# list Access_Control_Allow_Headers 'Lock-Token'
-# list Access_Control_Allow_Headers 'Timeout'
-# list Access_Control_Allow_Headers 'Destination'
-# list Access_Control_Allow_Headers 'Overwrite'
-# list Access_Control_Allow_Headers 'X-client'
-# list Access_Control_Allow_Headers 'X-Requested-With'
-# list Access_Control_Expose_Headers 'Etag'
-
-
-####################################################
-# Global logging options
-#
-config setting 'logging'
-
- # Set the default logging level to debug for all outputs (ignore output level settings)
- # Default: 0 (disabled)
-# option debug '1'
- # Log all environment variables (including those set in the shell) when starting
- # Default: 0 (disabled)
-# option full_environment '1'
-
-
-####################################################
-# Spezial logging options
-# !!! not documented in Radicale documentation
-# !!! special settings for this implementation
-#
-config logging 'logger'
-
- # Level: DEBUG | INFO | WARNING | ERROR | CRITICAL
- # To nearly disable logging set level to critical
-
- # log level on console
-# option console_level 'ERROR'
-
- # Here we use Rotating Logfiles in this implementation
- # !!! if maxbytes and/or backupcount is set to 0 !!!
- # !!! file rotation is disabled and logfile grows endless !!!
- # log level
-# option file_level 'INFO'
- # directory where log files are written
-# option file_path '/var/log/radicale'
- # max size of each logfile (see warning above)
-# option file_maxbytes '8196'
- # number of backup files to create (see warning above)
-# option file_backupcount '1'
-
- # log level for syslog logging
-# option syslog_level 'WARNING'
-
+++ /dev/null
-#!/bin/sh
-
-# only (re-)start on ifup
-[ "$ACTION" = "ifup" ] || exit 0
-# only start if boot_delay is done
-[ -f /tmp/radicale.hotplug ] || exit 0
-
-_PID=$(ps | grep '[p]ython.*[r]adicale' 2>/dev/null | awk '{print $1}')
-kill -1 $_PID 2>/dev/null
-if [ $? -eq 0 ]; then
- # only restart if already running
- logger -p user.info -t "radicale[$_PID]" \
- "Restart request due to '$ACTION' of interface '$INTERFACE'"
- /etc/init.d/radicale restart
-else
- # only start if enabled
- /etc/init.d/radicale enabled && /etc/init.d/radicale start
-fi
+++ /dev/null
-#!/bin/sh /etc/rc.common
-# Copyright (C) 2006-2016 OpenWrt.org
-
-START=80
-STOP=10
-
-extra_command "export_storage" "<PATH>
- - export the storage into the specified folder
- - <PATH> can be directly used with the default storage backend of Radicale 2.x.x."
-
-CFGDIR=/var/etc/radicale
-SYSCFG=$CFGDIR/config
-LOGCFG=$CFGDIR/logging
-
-DATADIR="/srv/radicale"
-LOGDIR=""
-
-PGREP="ps | grep '[p]ython.*[r]adicale' 2>/dev/null | awk '{print \$1}' "
-
-# we could start with empty configuration file using defaults
-[ -f /etc/config/radicale ] || touch /etc/config/radicale
-
-_uci2radicale() {
- local _SYSTMP="$SYSCFG.tmp"
- local _LOGTMP="$LOGCFG.tmp"
- local _LOPT # list option name
- local _LVAL # list option value
- local _STYPE # section type
- local _SNAME # section name
- local _console_level="ERROR" # logging console level
- local _file_level="INFO" # logging file level
- local _file_path="/var/log/radicale" # logging file path
- local _file_maxbytes="8196" # logging file maxBytes
- local _file_backupcount="1" # logging file backupCount
- local _syslog_level="WARNING" # logging syslog level
-
- # write list values to config
- _write_list() {
- _write_value "$_LOPT" "$_LVAL" # there might be spaces in _LVAL
- _LOPT=""
- _LVAL=""
- }
-
- _write_value() {
- # $1 option
- # $2 value
- local __OPT=$1
- local __VAL=$2
- # section "server" ignore option "daemon" and "pid"
- [ "$_SNAME" = "server" -a "$__OPT" = "daemon" ] && return 0
- [ "$_SNAME" = "server" -a "$__OPT" = "pid" ] && return 0
- # section "logging" ignore option "config" (logging config file)
- [ "$_SNAME" = "logging" -a "$__OPT" = "config" ] && return 0
- # section "auth" ignore option "htpasswd_filename" (htpasswd file)
- [ "$_SNAME" = "auth" -a "$__OPT" = "htpasswd_filename" ] && return 0
- # section "rights" ignore option "file" (reg-based rights file)
- [ "$_SNAME" = "rights" -a "$__OPT" = "file" ] && return 0
- # section "headers" replace "_" with "-" in option (UCI problem)
- [ "$_SNAME" = "headers" ] && __OPT=$(echo "$__OPT" | sed -e "s#_#-#g")
- # save data driectory
- [ "$_SNAME" = "storage" -a "$__OPT" = "filesystem_folder" ] && DATADIR="$__VAL"
- # special handling for well-known, value needs single quotes
- [ "$_SNAME" = "well-known" -a "${__VAL#*\%\(}" != "$__VAL" ] && __VAL="'$__VAL'"
- # handling of log settings
- if [ "$_STYPE" = "logging" -a "$_SNAME" = "logger" ]; then
- eval "_$__OPT='$__VAL'" # set to environment for later use
- else
- # handle bool
- [ "$__VAL" = "0" ] && __VAL="False"
- [ "$__VAL" = "1" ] && __VAL="True"
- # append data to the corresponding section
- sed -i "/\[$_SNAME\]/a $__OPT = $__VAL" $_SYSTMP
- fi
- }
-
- # redefined callback for sections when calling config_load
- config_cb() {
- # $1 "Type"
- # $2 "Name"
- # write out last list option
- [ -n "$_LOPT" ] && _write_list
- # mark invalid
- _STYPE=""
- _SNAME=""
- # check section type
- [ "$1" = "setting" -o "$1" = "logging" ] && {
- _STYPE="$1"
- _SNAME="$2"
- }
- # translate section name
- [ "$2" = "well_known" ] && _SNAME="well-known"
- return 0
- }
-
- # redefined callback for lists when calling config_load
- list_cb() {
- # $1 name of variable
- # $2 value
- # invalid section type then ignore
- [ -z "$_STYPE" -o -z "$_SNAME" ] && return 0
- # write out last list option if new list starts
- [ -n "$_LOPT" -a "$_LOPT" != "$1" ] && _write_list
- # new list option
- if [ -z "$_LOPT" ]; then
- _LOPT="$1"
- _LVAL="$2"
- else
- _LVAL="$_LVAL, $2"
- fi
- return 0
- }
-
- # redefined callback for options when calling config_load
- option_cb() {
- # $1 name of variable
- # $2 value
- local __OPT="$1"
- local __VAL="$2"
- # invalid section type then ignore
- [ -z "$_STYPE" -o -z "$_SNAME" ] && return 0
- # ignore list entrys will be handled by list_cb()
- [ "${__OPT#*_ITEM}" != "$__OPT" ] && return 0 # ignore lists *_ITEM*
- [ "${__OPT#*_LENGTH}" != "$__OPT" ] && return 0 # ignore lists *_LENGTH
- # write out last list option and clear
- [ -n "$_LOPT" ] && _write_list
- # write to file
- _write_value "$__OPT" "$__VAL" # there might be spaces in __VAL
- return 0
- }
-
- # temporary config file
- # radicale need read access
- mkdir -m0755 -p $CFGDIR
-
- cp /etc/radicale/config.template $_SYSTMP
- config_load radicale # calling above config_cb()/option_cb()/list_cb() and write into $_SYSTMP
- sed -i "/\[logging\]/a config = /var/etc/radicale/logging" $_SYSTMP # hard-code logging config
- sed -i "/\[auth\]/a htpasswd_filename = /etc/radicale/users" $_SYSTMP # hard-code htpasswd
- sed -i "/\[rights\]/a file = /etc/radicale/rights" $_SYSTMP # hard-code regexp-based rights
-
- # temporary logging config file
- cp /etc/radicale/logging.template $_LOGTMP
- LOGDIR="$_file_path"
- sed -i "/\[handler_console\]/a level = $_console_level" $_LOGTMP
- sed -i "/\[handler_file\]/a level = $_file_level" $_LOGTMP
- sed -i "/\[handler_file\]/a args = ('$_file_path/radicale','a',$_file_maxbytes,$_file_backupcount)" $_LOGTMP
- sed -i "/\[handler_syslog\]/a level = $_syslog_level" $_LOGTMP
-
- # move tmp to final
- mv -f $_SYSTMP $SYSCFG
- mv -f $_LOGTMP $LOGCFG
-}
-
-_set_permission() {
- # config file permissions (read access for group)
- chmod 644 $SYSCFG $LOGCFG
- chgrp -R radicale $CFGDIR
- # log directory (full access and owner)
- [ -d $LOGDIR ] || mkdir -m0755 -p $LOGDIR
- chown -R radicale:radicale $LOGDIR
- # data directory does not exist
- [ -d $DATADIR ] || {
- logger -p user.error -t "radicale[----]" "Data directory '$DATADIR' does not exists. Startup failed !!!"
- exit 1
- }
- chgrp -R radicale $DATADIR
-}
-
-export_storage() {
- # if already running do nothing
- local _PID=$(eval "$PGREP")
- kill -1 $_PID 2>/dev/null && {
- echo "Export failed !!! - Service running !" >&2
- logger -p user.error -t "radicale[$_PID]" "Export failed !!! - Service running !"
- return 1
- }
-
- [ $# -ne 1 ] || [ ! -d $1 ] && {
- echo "Export failed !!! Directory not given or does not exist !" >&2
- logger -p user.error -t "radicale[----]" "Export failed !!! Directory not given or does not exist !"
- return 1
- }
-
- _uci2radicale
- _set_permission
-
- chmod 775 $1
- chgrp radicale $1
-
- radicale --config=$SYSCFG --export-storage $1/export
-}
-
-boot() {
- # wait a given time (default 10 seconds) before startup
- # to wait for interfaces to come up / not using hotplug events during boot
- _start() {
- [ $1 -gt 0 ] && sleep $1
- start
- }
-
- local _DELAY
- _DELAY=$(uci_get "radicale" "system" "boot_delay" "10")
- _start $_DELAY &
- return 0
-}
-
-shutdown() {
- rm -f /tmp/radicale.hotplug
- stop
-}
-
-start() {
- _running() {
- sleep 2 # give radicale time to completely come up
- local _PID=$(eval "$PGREP")
- kill -1 $_PID 2>/dev/null
- [ $? -eq 0 ] \
- && logger -p user.notice -t "radicale[$_PID]" "Service started successfully"\
- || logger -p user.warn -t "radicale[----]" "Service failed to start"
- }
-
- # if already running do nothing
- local _PID=$(eval "$PGREP")
- kill -1 $_PID 2>/dev/null && return 0
-
- _uci2radicale
- _set_permission
-
- radicale --daemon --config=$SYSCFG
- touch /tmp/radicale.hotplug
-
- _running & # check if running and syslog
-
- return 0
-}
-
-reload() {
- # reload is also used by luci
- local _PID=$(eval "$PGREP")
- kill -1 $_PID 2>/dev/null
- if [ $? -eq 0 ]; then
- # only restart if already running
- restart
- else
- # only start if enabled
- enabled && start
- fi
- return 0
-}
-
-stop() {
- local _PID=$(eval "$PGREP")
- [ -z "$_PID" ] && return 0 # not running
- kill -15 $_PID 2>/dev/null
- sleep 3 # give time to shutdown
- local _tmp=$(eval "$PGREP")
- if [ -z "$_tmp" ]; then
- logger -p user.notice -t "radicale[$_PID]" "Service shutdown successfully"
- else
- kill -9 $_tmp # Normally never come here
- logger -p user.warn -t "radicale[----]" "Service shutdown FORCED"
- fi
- return 0
-}
+++ /dev/null
-#
-# Authentication login is matched against the "user" key, and collection's path is matched against the "collection" key.
-# You can use Python's ConfigParser interpolation values %(login)s and %(path)s.
-# You can also get groups from the user regex in the collection with {0}, {1}, etc.
-#
-# For example, for the "user" key, ".+" means "authenticated user" and ".*" means "anybody" (including anonymous users).
-#
-# Section names are only used for naming the rule.
-# Leading or ending slashes are trimmed from collection's path.
-#
-
-# This means all users starting with "admin" may read any collection
-[admin]
-user: ^admin.*$
-collection: .*
-permission: r
-
-# This means all users may read and write any collection starting with public.
-# We do so by just not testing against the user string.
-[public]
-user: .*
-collection: ^public(/.+)?$
-permission: rw
-
-# A little more complex: give read access to users from a domain for all
-[domain-wide-access]
-user: ^.+@(.+)\..+$
-collection: ^{0}/.+$
-permission: r
-
-# Allow authenticated user to read all collections
-[allow-everyone-read]
-user: .+
-collection: .*
-permission: r
-
-# Give write access to owners
-[owner-write]
-user: .+
-collection: ^%(login)s(/.+)?$
-permission: rw
-
-# Allow CardDavMATE-, CalDavZAP- or InfCloud- WEBclient to work
-# anonymous users have read access to "/" but no files or subdir
-[infcloud]
-user: .*
-collection: /
-permission: r
+++ /dev/null
-#
-# Sample File
-#
-
-user1:password1
-user2:password2
\ No newline at end of file
+++ /dev/null
-Subject: [PATCH] Run as user radicale and group radicale
-
-Patch to run Radicale service as radicale:radicale non root user
-
----
- bin/radicale | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/bin/radicale
-+++ b/bin/radicale
-@@ -26,6 +26,13 @@ Launch the server according to configura
-
- """
-
-+# inserted to run as user radicale
-+import pwd, grp, os
-+uid = pwd.getpwnam('radicale').pw_uid
-+gid = grp.getgrnam('radicale').gr_gid
-+os.setegid(gid)
-+os.seteuid(uid)
-+
- import radicale.__main__
-
-